package client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;

import clientCommunicationHandler.ClientServerMsgHandler;
import clientCommunicationHandler.UserInterfaceMsgHandler;

public class TelnetClient {

	public static String userName = "guest";
	public static String tempUserName = "guest";
	public static int SubForumId = -1;
	public static StringBuilder menu = new StringBuilder("[user: "+TelnetClient.userName+"] please make your choice:\n\t1. Login\n\t2. Register\n\t3. view_Forums\n\t4. Exit");
	public static StringBuilder welcom_page = new StringBuilder("please make your choice:\n\t1. Login\n\t2. Register\n\t3. view_Forums\n\t4. Exit");
	public static boolean transmitToServer = true;//true if the message should be sent to the server
	public static int threadId = -1;
	public static int postId = -1;
	public static int tempThreadID = -1;
	public static int tempSubForumID =-1;
	public static BufferedReader in;
	public static boolean Debug = false;



	public static void main(String[] args) throws Exception{
		if (args.length != 2){
			System.err.println("UsageL "+TelnetClient.class.getSimpleName()+"<host><port>");
			return;
		}

		//parse options
		String host = args[0];
		int port = Integer.parseInt(args[1]);

		//Configure the client
		ClientBootstrap bootstrap = new ClientBootstrap
				(new NioClientSocketChannelFactory
						(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));

		//configure the pipe line factory
		bootstrap.setPipelineFactory(new TelnetClientPipelineFactory());

		//start the connection attempt
		ChannelFuture future = bootstrap.connect(new InetSocketAddress(host,port));

		//wait until the connection attempt succeeds or fails.
		Channel channel = future.awaitUninterruptibly().getChannel();
		if(!future.isSuccess()){
			future.getCause().printStackTrace();
			bootstrap.releaseExternalResources();
			return;
		}

		ChannelFuture lastWriteFuture = null;
		TelnetClient.in = new BufferedReader(new InputStreamReader(System.in));
		String line ;
		System.out.println("welcom to our Forum.");
		UserInterfaceMsgHandler userMsgHandler = new UserInterfaceMsgHandler();

		//listen to user
		for(;;){
			transmitToServer = true;
			line = null;

			//parse the user input.the input should be a number.
			System.out.println(menu);
			String [] tMenuInArray = menu.toString().split("\t");
			int tUserRequest = 0;
			while(line == null){
				line = in.readLine();
				if(TelnetClient.Debug){
					if ( line.equalsIgnoreCase("exit")){
						channel.getCloseFuture().awaitUninterruptibly();
						break;
					}
				}
				try{
					tUserRequest = Integer.parseInt(line);
					if(!(tUserRequest>0 && tUserRequest < tMenuInArray.length)){
						line = null;
						System.out.println("please enter number from 1 to "+tMenuInArray.length);
					}
				}
				catch(Exception e){
					line = null;
					System.out.println("invalid input please enter a number");
				}
			}
			line = userMsgHandler.parserUserMsg(tUserRequest,tMenuInArray);//take care of the user requests.parse the menu choice into legal protocol.
			ClientServerMsgHandler.isReady = false;

			if(line == null){
				break;
			}
			if(transmitToServer)
				//sends the received line to the server 
				lastWriteFuture = channel.write(line);

			//If user typed 'exit' command wait until server closes the connection
			if ( line.equalsIgnoreCase("exit")){
				channel.getCloseFuture().awaitUninterruptibly();
				break;
			}
			if(transmitToServer){
				synchronized (ClientServerMsgHandler.class) {
					System.out.println("flag = " +ClientServerMsgHandler.isReady);
					if(ClientServerMsgHandler.isReady == false)
						ClientServerMsgHandler.class.wait();
				}
			}
			System.out.println("out of wait");



		}

		//wait until all messages are flushed before closing the channel.


		{
			lastWriteFuture.awaitUninterruptibly();
		}


		//close the connection. Make sure the close operation ends
		//because all I/O operation are asynchronous in Netty
		channel.close().awaitUninterruptibly();

		//Shut down all thread pools to exit.
		bootstrap.releaseExternalResources();

	}//ends main


}
